

/*
 * @namespace Browser
 * @aka L.Browser
 *
 * A namespace with static properties for browser/feature detection used by Leaflet internally.
 *
 * @example
 *
 * ```js
 * if (L.Browser.ielt9) {
 *   alert('Upgrade your browser, dude!');
 * }
 * ```
 */

export default class Browser {
	public static userAgentContains(str) {
		return navigator.userAgent.toLowerCase().indexOf(str) >= 0;
	}
	// @property ie: Boolean; `true` for all Internet Explorer versions (not Edge).
	public static ie = 'ActiveXObject' in window;

	// @property ielt9: Boolean; `true` for Internet Explorer versions less than 9.
	public static ielt9 = Browser.ie && !document.addEventListener;

	// @property edge: Boolean; `true` for the Edge web browser.
	public static edge = 'msLaunchUri' in navigator && !('documentMode' in document);

	// @property webkit: Boolean;
	// `true` for webkit-based browsers like Chrome and Safari (including mobile versions).
	public static webkit = Browser.userAgentContains('webkit');

	// @property android: Boolean
	// `true` for any browser running on an Android platform.
	public static android = Browser.userAgentContains('android');

	// @property android23: Boolean; `true` for browsers running on Android 2 or Android 3.
	public static android23 = Browser.userAgentContains('android 2') || Browser.userAgentContains('android 3');

	/* See https://stackoverflow.com/a/17961266 for details on detecting stock Android */
	public static webkitVer = parseInt(/WebKit\/([0-9]+)|$/.exec(navigator.userAgent)[1], 10); // also matches AppleWebKit
	// @property androidStock: Boolean; `true` for the Android stock browser (i.e. not Chrome)
	public static androidStock = Browser.android && Browser.userAgentContains('Google') && Browser.webkitVer < 537 && !('AudioNode' in window);

	// @property opera: Boolean; `true` for the Opera browser
	public static opera = !!window['opera'];

	// @property chrome: Boolean; `true` for the Chrome browser.
	public static chrome = Browser.userAgentContains('chrome');

	// @property gecko: Boolean; `true` for gecko-based browsers like Firefox.
	public static gecko = Browser.userAgentContains('gecko') && !Browser.webkit && !Browser.opera && !Browser.ie;

	// @property safari: Boolean; `true` for the Safari browser.
	public static safari = !Browser.chrome && Browser.userAgentContains('safari');

	public static phantom = Browser.userAgentContains('phantom');

	// @property opera12: Boolean
	// `true` for the Opera browser supporting CSS transforms (version 12 or later).
	public static opera12 = 'OTransition' in document.documentElement.style;

	// @property win: Boolean; `true` when the browser is running in a Windows platform
	public static win = navigator.platform.indexOf('Win') === 0;

	// @property ie3d: Boolean; `true` for all Internet Explorer versions supporting CSS transforms.
	public static ie3d = Browser.ie && ('transition' in document.documentElement.style);

	// @property webkit3d: Boolean; `true` for webkit-based browsers supporting CSS transforms.
	public static webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()) && !Browser.android23;

	// @property gecko3d: Boolean; `true` for gecko-based browsers supporting CSS transforms.
	public static gecko3d = 'MozPerspective' in document.documentElement.style;

	// @property any3d: Boolean
	// `true` for all browsers supporting CSS transforms.
	public static any3d = !window['L_DISABLE_3D'] && (Browser.ie3d || Browser.webkit3d || Browser.gecko3d) && !Browser.opera12 && !Browser.phantom;

	// @property mobile: Boolean; `true` for all browsers running in a mobile device.
	public static mobile = typeof orientation !== 'undefined' || Browser.userAgentContains('mobile');

	// @property mobileWebkit: Boolean; `true` for all webkit-based browsers in a mobile device.
	public static mobileWebkit = Browser.mobile && Browser.webkit;

	// @property mobileWebkit3d: Boolean
	// `true` for all webkit-based browsers in a mobile device supporting CSS transforms.
	public static mobileWebkit3d = Browser.mobile && Browser.webkit3d;

	// @property msPointer: Boolean
	// `true` for browsers implementing the Microsoft touch events model (notably IE10).
	public static msPointer = !window.PointerEvent && window.PointerEvent;

	// @property pointer: Boolean
	// `true` for all browsers supporting [pointer events](https://msdn.microsoft.com/en-us/library/dn433244%28v=vs.85%29.aspx).
	public static pointer = !!(window.PointerEvent || Browser.msPointer);

	// @property touch: Boolean
	// `true` for all browsers supporting [touch events](https://developer.mozilla.org/docs/Web/API/Touch_events).
	// This does not necessarily mean that the browser is running in a computer with
	// a touchscreen, it only means that the browser is capable of understanding
	// touch events.
	public static touch = !window['L_NO_TOUCH'] && (Browser.pointer || 'ontouchstart' in window ||
		(window['DocumentTouch'] && document instanceof window['DocumentTouch']));

	// @property mobileOpera: Boolean; `true` for the Opera browser in a mobile device.
	public static mobileOpera = Browser.mobile && Browser.opera;

	// @property mobileGecko: Boolean
	// `true` for gecko-based browsers running in a mobile device.
	public static mobileGecko = Browser.mobile && Browser.gecko;

	// @property retina: Boolean
	// `true` for browsers on a high-resolution "retina" screen.
	public static retina = (window.devicePixelRatio || (window.screen['deviceXDPI'] / window.screen['logicalXDPI'])) > 1;


	// @property canvas: Boolean
	// `true` when the browser supports [`<canvas>`](https://developer.mozilla.org/docs/Web/API/Canvas_API).
	public static canvas = (function () {
		return !!document.createElement('canvas').getContext;
	}());


}
